package com.sk.ccflower.server.lib.sockUtils.nio;

import java.nio.channels.SelectionKey;
import java.util.Date;

public abstract class NioHandler 
{
	private Date m_date = null;
	private long m_nextTimeoutSec = 0;
	private long m_timeoutIntervalSec = 0;
	
	public NioHandler()
	{
	}

	/** 
	 * 주기적으로 timeout에 의한 동작을 하고자 할때 등록, timeout이 발생하면 handleTimeout() 함수가 호출된다.
	 * @param timeoutIntervalSec: timeout이 발생하는 주기 (초단위)
	 */
	protected void registerTimeout(long timeoutIntervalSec)
	{
		if(timeoutIntervalSec<=0) return;
		
		m_timeoutIntervalSec = timeoutIntervalSec;
		m_nextTimeoutSec = (System.currentTimeMillis()/1000) + timeoutIntervalSec;
	}
	
	/**
	 * 등록한 timeout을 해지함.
	 */
	protected void removeTimeout()
	{
		m_timeoutIntervalSec = 0;
	}
	
	/**
	 * 설정되어 있는 timeout을 가져옴
	 */
	protected long getTimeout()
	{
		return m_timeoutIntervalSec;
	}
	
	protected void setNexTimeout(long curentTimeSec)
	{
		if(m_timeoutIntervalSec<=0) return;
		
		if(m_nextTimeoutSec==0) m_nextTimeoutSec = curentTimeSec + m_timeoutIntervalSec;

		while(true) {
			if(m_nextTimeoutSec>curentTimeSec) break;
			m_nextTimeoutSec += m_timeoutIntervalSec;
		}
	}
	
	protected long getNextTimeout()
	{
		return m_nextTimeoutSec;
	}
	
	protected final Date getDate(long currentTimeMillis)
	{
		if(m_date==null) m_date = new Date();
		m_date.setTime(currentTimeMillis);
		return m_date;
	}
	
	protected final Date getDate()
	{
		return m_date;
	}
	
	/**
	 * 등록된 SelectableChannel에서 input이 들어오면 호출됨.
	 */
	protected abstract void handleInput(SelectionKey key);
	
	/**
	 * Timeout을 등록하고 해당 timeout이 발생하면 호출됨.
	 */
	protected abstract void handleTimeout(SelectionKey key, Date date);
}
